<template>
  <div class="app-container">
    <el-card>
      <!-- 按钮区域 -->
      <div class="btn-container">
        <el-button type="primary" icon="el-icon-plus" @click="handleCreate">
          添加
        </el-button>
      </div>

      <!-- 表格区域 -->
      <el-table :data="list" row-key="id" border :expand-row-keys="expendArr" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
        <el-table-column prop="title" label="菜单名称" :show-overflow-tooltip="true" />
        <el-table-column label="图标" :show-overflow-tooltip="true">
          <template slot-scope="{ row }">
            <i :class="row.icon" style="font-size: 24px" />
            {{ row.icon }}
          </template>
        </el-table-column>
        <el-table-column label="级别" width="80">
          <template slot-scope="{ row }">
            <el-tag :type="row.level | levelFilter">{{ row.level }}级</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="code" label="前端路由" :show-overflow-tooltip="true" />
        <el-table-column label="操作" width="150">
          <template slot-scope="{ row }">
            <el-button type="primary" size="mini" @click="handleUpdate(row)">
              编辑
            </el-button>
            <el-button v-if="row.children == [] || !row.children" type="danger" size="mini" @click="handleDelete(row)">
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 添加/编辑对话框 -->
    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" :close-on-click-modal="false" @close="resetForm('dataForm')">
      <el-form ref="dataForm" :rules="rules" :model="temp" label-position="right" label-width="80px">
        <el-form-item label="菜单名称" prop="title">
          <el-input v-model.trim="temp.title" />
        </el-form-item>
        <el-form-item label="图标">
          <el-input v-model.trim="temp.icon" />
        </el-form-item>
        <el-form-item label="类型" prop="type">
          <el-select v-model="temp.type" placeholder="请选择">
            <el-option label="目录" value="dirt" />
            <el-option label="菜单" value="menu" />
          </el-select>
        </el-form-item>
        <el-form-item label="前端路由" prop="code">
          <el-cascader v-model="selectedKeys2" :options="viewsList" :props="props2" filterable @change="selectedChange2" />
        </el-form-item>
        <el-form-item label="父级">
          <el-cascader v-model="selectedKeys1" :options="list" :props="props1" clearable filterable @change="selectedChange1" />
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model.trim="temp.description" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false"> 取 消 </el-button>
        <el-button type="primary" @click="dialogStatus === 'create' ? createData('dataForm') : updateData('dataForm')">
          确 定
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { fetchTree, addObj, getObj, putObj, delObj } from '@/api/base/menu' // 菜单模块的接口
import { isEmpty, addLevel, getTreeDeepArr, isDiffForm } from '@/utils' // 公共方法
import { viewsList } from '@/router' // 获取本地需要权限控制的页面

export default {
  name: 'Menu',
  filters: {
    // 局部过滤器
    typeFilter(type) {
      return type === 'dirt' ? '目录' : '菜单'
    }
  },
  data() {
    return {
      list: [], // 列表数据
      expendArr: [], // 列表默认展开项
      temp: {
        // 表单数据
        title: '',
        icon: '',
        type: '',
        code: '',
        parentId: '-1',
        description: ''
      },
      originalForm: null, // 编辑时的表单原始数据
      dialogFormVisible: false, // 控制对话框显示或隐藏
      dialogStatus: '', // 对话框状态
      textMap: {
        // 对话框标题
        update: '编辑',
        create: '添加'
      },
      rules: {
        // 表单规则
        title: [
          { required: true, message: '请输入名称', trigger: 'blur' },
          { min: 1, max: 10, message: '长度不能大于10位', trigger: 'blur' }
        ],
        icon: [{ required: true, message: '请输入图标', trigger: 'blur' }],
        type: [{ required: true, message: '请选择类型', trigger: 'change' }],
        code: [{ required: true, message: '请选择指向页面', trigger: 'change' }]
      },
      props1: {
        // 父级菜单配置项
        value: 'id',
        label: 'title',
        children: 'children',
        checkStrictly: true
      },
      selectedKeys1: [], // 父级菜单选中项
      props2: {
        // 前端路由配置项
        value: 'id',
        label: 'name',
        children: 'children',
        checkStrictly: true
      },
      selectedKeys2: [], // 前端路由选中项
      viewsList: [] // 本地需要权限控制的页面数据
    }
  },
  created() {
    // 组件创建完成
    this.getList()
    this.viewsList = viewsList
  },
  methods: {
    async getList() {
      // 获取列表数据
      try {
        const data = await fetchTree()
        addLevel(data)
        this.list = data
        for (const item of data) {
          this.expendArr.push(item.id)
        }
      } catch (error) {
        console.log(error)
      }
    },
    selectedChange1(value) {
      // 父级选择器变化时
      if (isEmpty(value)) {
        this.temp.parentId = value[value.length - 1]
      } else {
        this.temp.parentId = '-1'
      }
    },
    selectedChange2(value) {
      // 前端路由选择器变化时
      this.temp.code = value[value.length - 1]
    },
    handleCreate() {
      // 点击添加按钮
      this.dialogStatus = 'create'
      this.dialogFormVisible = true
    },
    createData(formName) {
      // 添加
      this.$refs[formName].validate(async (valid) => {
        if (valid) {
          try {
            const { message } = await addObj(this.temp)
            this.dialogFormVisible = false
            this.$message({
              message: message,
              type: 'success'
            })
            this.getList()
          } catch (error) {
            console.log(error)
          }
        }
      })
    },
    async handleUpdate(row) {
      // 点击编辑
      this.dialogStatus = 'update'
      this.dialogFormVisible = true
      const { data } = await getObj(row.id)
      this.temp = {
        id: row.id,
        title: data.title,
        icon: data.icon,
        type: data.type,
        code: data.code,
        parentId: data.parentId,
        description: data.description
      }
      this.selectedKeys1 = getTreeDeepArr(data.parentId, this.list)
      this.selectedKeys2 = getTreeDeepArr(data.code, viewsList)
      this.originalForm = { ...this.temp }
    },
    updateData(formName) {
      // 点击编辑按钮
      this.$refs[formName].validate(async (valid) => {
        if (valid) {
          if (!isDiffForm(this.temp, this.originalForm)) {
            this.$message({
              message: '未修改数据不提交！',
              type: 'error'
            })
            this.dialogFormVisible = false
            return false
          }
          try {
            const { message } = await putObj(this.temp.id, this.temp)
            this.dialogFormVisible = false
            this.$message({
              message: message,
              type: 'success'
            })
            this.getList()
          } catch (error) {
            console.log(error)
          }
        }
      })
    },
    handleDelete(row, index) {
      // 点击删除按钮
      this.$confirm('此操作将永久删除, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async () => {
          try {
            await delObj(row.id)
            this.$message.success('删除成功！')
            this.getList()
          } catch (error) {
            console.log(error)
          }
        })
        .catch(() => {})
    },
    resetForm(formName) {
      // 对话框关闭时重置表单
      this.selectedKeys1 = []
      this.selectedKeys2 = []
      this.originalForm = null
      this.temp = {
        title: '',
        icon: '',
        type: '',
        code: '',
        parentId: '-1',
        description: ''
      }
      this.$refs[formName].resetFields()
    }
  }
}
</script>
